<template>
  <div class="visitor-trend-chart">
    <div ref="chartRef" class="chart-container"></div>
  </div>
</template>

<script setup>
/**
 * 访客趋势图表组件
 * 
 * 基于Echarts实现的访客趋势图表，支持周、月、年三种时间范围的数据展示
 */
import { ref, onMounted, watch, onUnmounted } from 'vue'
import * as echarts from 'echarts'
import { useElementSize } from '@vueuse/core'

const props = defineProps({
  /**
   * 时间范围类型
   * 支持 week, month, year 三种类型
   */
  timeRange: {
    type: String,
    default: 'month',
    validator: (value) => ['week', 'month', 'year'].includes(value)
  }
})

// 图表DOM引用
const chartRef = ref(null)
// 监听容器尺寸
const { width, height } = useElementSize(chartRef)
// 图表实例
let chartInstance = null

/**
 * 生成模拟数据
 * 根据时间范围生成不同的数据集
 */
const generateMockData = (range) => {
  let xAxisData = []
  let yAxisData = []
  let uvData = []
  
  switch (range) {
    case 'week':
      // 最近7天数据
      xAxisData = Array.from({ length: 7 }, (_, i) => {
        const date = new Date()
        date.setDate(date.getDate() - (6 - i))
        return `${date.getMonth() + 1}/${date.getDate()}`
      })
      yAxisData = [1200, 1350, 1800, 1420, 1650, 2100, 2400]
      uvData = [980, 1100, 1300, 1150, 1220, 1800, 2050]
      break
      
    case 'month':
      // 最近30天数据
      xAxisData = Array.from({ length: 30 }, (_, i) => {
        const date = new Date()
        date.setDate(date.getDate() - (29 - i))
        return `${date.getMonth() + 1}/${date.getDate()}`
      })
      yAxisData = Array.from({ length: 30 }, () => Math.floor(Math.random() * 2000 + 1000))
      uvData = yAxisData.map(val => Math.floor(val * (0.7 + Math.random() * 0.2)))
      break
      
    case 'year':
      // 最近12个月数据
      const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
      xAxisData = months
      yAxisData = [15800, 13200, 14500, 18000, 22500, 25800, 30000, 32500, 28000, 26000, 30500, 35000]
      uvData = [12500, 10800, 11900, 14500, 18000, 21000, 24500, 26800, 22000, 20500, 25000, 29500]
      break
  }
  
  return { xAxisData, yAxisData, uvData }
}

/**
 * 初始化图表
 */
const initChart = () => {
  if (!chartRef.value) return
  
  // 初始化echarts实例
  chartInstance = echarts.init(chartRef.value)
  
  // 更新图表
  updateChart()
  
  // 响应窗口尺寸变化
  window.addEventListener('resize', resizeChart)
}

/**
 * 更新图表数据和配置
 */
const updateChart = () => {
  if (!chartInstance) return
  
  // 获取模拟数据
  const { xAxisData, yAxisData, uvData } = generateMockData(props.timeRange)
  
  // 图表配置选项
  const option = {
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(255, 255, 255, 0.9)',
      borderColor: '#eee',
      borderWidth: 1,
      textStyle: {
        color: '#333'
      },
      formatter: (params) => {
        let result = `<div style="font-weight:bold;margin-bottom:5px;">${params[0].name}</div>`
        params.forEach(item => {
          result += `<div style="display:flex;align-items:center;margin:3px 0;">
            <span style="display:inline-block;width:10px;height:10px;background:${item.color};border-radius:50%;margin-right:5px;"></span>
            <span>${item.seriesName}：${item.value.toLocaleString()}</span>
          </div>`
        })
        return result
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      top: '5%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: xAxisData,
      axisLine: {
        lineStyle: {
          color: '#eee'
        }
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: '#999'
      }
    },
    yAxis: {
      type: 'value',
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      splitLine: {
        lineStyle: {
          color: '#eee',
          type: 'dashed'
        }
      },
      axisLabel: {
        color: '#999',
        formatter: (value) => {
          if (value >= 1000) {
            return (value / 1000) + 'k'
          }
          return value
        }
      }
    },
    series: [
      {
        name: 'PV浏览量',
        type: 'line',
        stack: 'Total',
        smooth: true,
        lineStyle: {
          width: 3,
          color: '#409EFF'
        },
        showSymbol: false,
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            {
              offset: 0,
              color: 'rgba(64, 158, 255, 0.4)'
            },
            {
              offset: 1,
              color: 'rgba(64, 158, 255, 0.1)'
            }
          ])
        },
        data: yAxisData
      },
      {
        name: 'UV访客数',
        type: 'line',
        stack: 'Total',
        smooth: true,
        lineStyle: {
          width: 3,
          color: '#67C23A'
        },
        showSymbol: false,
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            {
              offset: 0,
              color: 'rgba(103, 194, 58, 0.4)'
            },
            {
              offset: 1,
              color: 'rgba(103, 194, 58, 0.1)'
            }
          ])
        },
        data: uvData
      }
    ]
  }
  
  // 设置图表选项
  chartInstance.setOption(option)
}

/**
 * 调整图表大小
 */
const resizeChart = () => {
  chartInstance && chartInstance.resize()
}

/**
 * 监听时间范围变化，更新图表
 */
watch(() => props.timeRange, (newRange) => {
  updateChart()
})

/**
 * 监听容器尺寸变化，更新图表大小
 */
watch([width, height], () => {
  resizeChart()
})

/**
 * 组件挂载时初始化图表
 */
onMounted(() => {
  initChart()
})

/**
 * 组件卸载时销毁图表实例
 */
onUnmounted(() => {
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
  window.removeEventListener('resize', resizeChart)
})
</script>

<style lang="scss" scoped>
.visitor-trend-chart {
  width: 100%;
  height: 100%;
  
  .chart-container {
    width: 100%;
    height: 100%;
  }
}
</style> 